package com.isdepci.project.carbon.service.impl;

import com.isdepci.framework.web.domain.AjaxResult;
import com.isdepci.project.carbon.domain.BHeatEmission;
import com.isdepci.project.carbon.domain.BHeatEmissionParameter;
import com.isdepci.project.carbon.domain.param.WeatherDataExcel;
import com.isdepci.project.carbon.mapper.BHeatEmissionMapper;
import com.isdepci.project.carbon.mapper.BHeatEmissionParameterMapper;
import com.isdepci.project.carbon.service.IBHeatEmissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * 热力排放Service业务层处理
 *
 * @author isdepci
 * @date 2025-03-29
 */
@Service
public class BHeatEmissionServiceImpl implements IBHeatEmissionService
{
    @Autowired
    private BHeatEmissionMapper bHeatEmissionMapper;
    @Autowired
    private BHeatEmissionParameterMapper bHeatEmissionParameterMapper;

//    // 数据库中获取所有的热焓数据
//    private List<BHeatEmissionParameter> getAllHeatValues(Integer steamType) {
//        return bHeatEmissionParameterMapper.getHeatValuesByType(steamType);
//    }
//
//    /**
//     * 查询蒸汽对应热焓值
//     */
//    @Override
//    public BHeatEmissionParameter getHeatValue(BHeatEmissionParameter parameter) {
//        // 根据选择的蒸汽类型获取对应的热焓数据
//        Integer steamType = parameter.getSteamType();  // 获取选择的蒸汽类型
//        List<BHeatEmissionParameter> allHeatValues = getAllHeatValues(steamType);  // 获取类型对应的数据
//        BHeatEmissionParameter heatValue = bHeatEmissionParameterMapper.getHeatValue(parameter);
//
//        if (heatValue != null) {
//            return heatValue; // 找到直接的热焓值
//        } else {
//            // 如果没有直接的热焓值，就进行插值计算
//            return interpolateHeatValue(parameter, allHeatValues);
//        }
//    }
//
//    private BHeatEmissionParameter interpolateHeatValue(BHeatEmissionParameter parameter, List<BHeatEmissionParameter> allHeatValues) {
//        BHeatEmissionParameter lowerTemp = null;
//        BHeatEmissionParameter upperTemp = null;
//        BHeatEmissionParameter lowerPressure = null;
//        BHeatEmissionParameter upperPressure = null;
//
//        // 寻找温度和压力的上下边界
//        for (BHeatEmissionParameter heat : allHeatValues) {
//            // 寻找温度的上下边界
//            if (heat.getSteamTemperature().compareTo(parameter.getSteamTemperature()) <= 0) {
//                lowerTemp = heat; // 小于等于当前温度的热焓值
//            } else {
//                upperTemp = heat; // 大于当前温度的热焓值
//                break;
//            }
//        }
//        for (BHeatEmissionParameter heat : allHeatValues) {
//            // 寻找压力的上下边界
//            if (heat.getSteamPressure().compareTo(parameter.getSteamPressure()) <= 0) {
//                lowerPressure = heat; // 小于等于当前压力的热焓值
//            } else {
//                upperPressure = heat; // 大于当前压力的热焓值
//                break;
//            }
//        }
//
//        if (lowerTemp != null && upperTemp != null && lowerPressure != null && upperPressure != null) {
//            return perform2DInterpolation(lowerTemp, upperTemp, lowerPressure, upperPressure, parameter);
//        }
//        return null;
//    }
//
//
//    /**
//     * 执行线性插值计算
//     */
//    private BHeatEmissionParameter perform2DInterpolation(BHeatEmissionParameter lowerTemp, BHeatEmissionParameter upperTemp, BHeatEmissionParameter lowerPressure, BHeatEmissionParameter upperPressure, BHeatEmissionParameter parameter) {
//        BigDecimal t1 = lowerTemp.getSteamTemperature();
//        BigDecimal t2 = upperTemp.getSteamTemperature();
//        BigDecimal p1 = lowerPressure.getSteamPressure();
//        BigDecimal p2 = upperPressure.getSteamPressure();
//        BigDecimal h11 = lowerTemp.getEnthalpy();
//        BigDecimal h12 = upperTemp.getEnthalpy();
//        BigDecimal h21 = lowerPressure.getEnthalpy();
//        BigDecimal h22 = upperPressure.getEnthalpy();
//        BigDecimal t = parameter.getSteamTemperature();
//        BigDecimal p = parameter.getSteamPressure();
//
//        // 修正压力插值部分
//        BigDecimal h1 = h11.add(h12.subtract(h11).multiply(p.subtract(p1)).divide(p2.subtract(p1), BigDecimal.ROUND_HALF_UP));  // 温度插值
//        BigDecimal h2 = h21.add(h22.subtract(h21).multiply(p.subtract(p1)).divide(p2.subtract(p1), BigDecimal.ROUND_HALF_UP));  // 温度插值
//
//        // 修正温度插值部分
//        BigDecimal interpolatedEnthalpy = h1.add(h2.subtract(h1).multiply(t.subtract(t1)).divide(t2.subtract(t1), BigDecimal.ROUND_HALF_UP));
//
//        interpolatedEnthalpy = interpolatedEnthalpy.setScale(2, BigDecimal.ROUND_HALF_UP);
//        // 返回插值结果
//        BHeatEmissionParameter result = new BHeatEmissionParameter();
//        result.setSteamType(parameter.getSteamType());
//        result.setSteamTemperature(parameter.getSteamTemperature());
//        result.setSteamPressure(parameter.getSteamPressure());
//        result.setEnthalpy(interpolatedEnthalpy);
//        return result;
//    }



    @Override
    public BHeatEmissionParameter getHeatValue(BHeatEmissionParameter parameter) {
        // 先尝试查询数据库
        BHeatEmissionParameter result = bHeatEmissionParameterMapper.getHeatValue(parameter);
        if (result != null) {
            return result;
        }

        Integer steamType = parameter.getSteamType();
        BigDecimal targetTemp = parameter.getSteamTemperature();
        BigDecimal targetPressure = parameter.getSteamPressure();

        // 查找温度邻近点
        BHeatEmissionParameter prevTemp = bHeatEmissionParameterMapper.findPrevTemperature(steamType, targetTemp);
        BHeatEmissionParameter nextTemp = bHeatEmissionParameterMapper.findNextTemperature(steamType, targetTemp);

        BigDecimal enthalpy = calculateInterpolatedEnthalpy(steamType, targetTemp, targetPressure, prevTemp, nextTemp);

        if (enthalpy == null) {
            // 处理无法插值的情况，例如抛出异常或返回null
            throw new RuntimeException("无法找到合适的邻近数据进行插值计算");
        }

        // 确保热焓值保留两位小数
        enthalpy = enthalpy.setScale(2, RoundingMode.HALF_UP);

        // 构建返回对象
        BHeatEmissionParameter interpolatedParam = new BHeatEmissionParameter();
        interpolatedParam.setSteamType(steamType);
        interpolatedParam.setSteamTemperature(targetTemp);
        interpolatedParam.setSteamPressure(targetPressure);
        interpolatedParam.setEnthalpy(enthalpy);
        return interpolatedParam;
    }

    private BigDecimal calculateInterpolatedEnthalpy(Integer steamType, BigDecimal targetTemp, BigDecimal targetPressure,
                                                     BHeatEmissionParameter prevTemp, BHeatEmissionParameter nextTemp) {
        List<BigDecimal> enthalpies = new ArrayList<>();

        // 收集可能的邻近点热焓值
        if (prevTemp != null) {
            BHeatEmissionParameter closestPressurePrev = bHeatEmissionParameterMapper.findClosestPressureForTemperature(steamType, prevTemp.getSteamTemperature(), targetPressure);
            if (closestPressurePrev != null) {
                enthalpies.add(closestPressurePrev.getEnthalpy());
            }
        }
        if (nextTemp != null) {
            BHeatEmissionParameter closestPressureNext = bHeatEmissionParameterMapper.findClosestPressureForTemperature(steamType, nextTemp.getSteamTemperature(), targetPressure);
            if (closestPressureNext != null) {
                enthalpies.add(closestPressureNext.getEnthalpy());
            }
        }

        // 如果没有找到任何数据，返回null
        if (enthalpies.isEmpty()) {
            return null;
        }

        // 如果有多个数据点，进行线性插值
        if (enthalpies.size() == 2 && prevTemp != null && nextTemp != null) {
            BigDecimal tempDelta = nextTemp.getSteamTemperature().subtract(prevTemp.getSteamTemperature());
            if (tempDelta.compareTo(BigDecimal.ZERO) == 0) {
                return enthalpies.get(0); // 温度相同，直接返回任意一个
            }
            BigDecimal tempRatio = targetTemp.subtract(prevTemp.getSteamTemperature()).divide(tempDelta, 4, RoundingMode.HALF_UP);
            BigDecimal enthalpyDelta = enthalpies.get(1).subtract(enthalpies.get(0));
            return enthalpies.get(0).add(enthalpyDelta.multiply(tempRatio));
        } else {
            // 只有一个数据点，直接返回
            return enthalpies.get(0);
        }
    }





    @Override
    public AjaxResult calHeatEmission(Long projectId) {
        // 查询所有BHeatEmission数据
        List<BHeatEmission> bHeatEmissions = bHeatEmissionMapper.selectBHeatEmissionListByProjectId(projectId);

        // 初始化总的热力碳排放
        BigDecimal totalHeatEmission = BigDecimal.ZERO;

        // 遍历每一条数据进行计算
        for (BHeatEmission bHeatEmission : bHeatEmissions) {
            // 判断是否是热量单位
            BigDecimal heatEmission = BigDecimal.ZERO;
            if (bHeatEmission.getIsHeat() == 1) {
                // 如果是热量单位，直接计算
                heatEmission = bHeatEmission.getBuyHeat().multiply(bHeatEmission.getHeatEmissionFactor());
            } else {
                // 如果不是热量单位，根据unitType判断是热水还是蒸汽
                BigDecimal adHeat = BigDecimal.ZERO;
                if (bHeatEmission.getUnitType() == 1) {
                    // 计算AD热水
                    adHeat = bHeatEmission.getWaterMass()
                            .multiply(bHeatEmission.getWaterTemperature().subtract(BigDecimal.valueOf(20)))
                            .multiply(BigDecimal.valueOf(4.1868E-3));  // 4.1868 * 10^-3
                } else if (bHeatEmission.getUnitType() == 2) {
                    // 计算AD蒸汽
                    adHeat = bHeatEmission.getSteamMass()
                            .multiply(bHeatEmission.getEnthalpy().subtract(BigDecimal.valueOf(83.74)))
                            .multiply(BigDecimal.valueOf(1E-3));  // 10^-3
                }
                // 计算热力碳排放
                heatEmission = adHeat.multiply(bHeatEmission.getHeatEmissionFactor());
            }
            bHeatEmission.setCarbonEmissions(heatEmission);
            bHeatEmissionMapper.updateBHeatEmission(bHeatEmission);
            // 累加到总和
            totalHeatEmission = totalHeatEmission.add(heatEmission);
        }
        // 返回总的热力碳排放
        return AjaxResult.success(totalHeatEmission.setScale(2, RoundingMode.HALF_UP));
    }

    public AjaxResult changeDataByProjectId(WeatherDataExcel excel) {
        List<BHeatEmission> list =  excel.getHeatEmissionList();
        list.forEach(item->{
            if(excel.getProjectId()!=null){
                item.setProjectId(excel.getProjectId());
            }
        });
        if(list.size()>0){
            bHeatEmissionMapper.insertList(list);
        }
        return AjaxResult.success();
    }



    /**
     * 查询热力排放
     */
    @Override
    public BHeatEmission selectBHeatEmissionById(Long id)
    {
        return bHeatEmissionMapper.selectBHeatEmissionById(id);
    }

    /**
     * 查询热力排放列表
     */
    @Override
    public List<BHeatEmission> selectBHeatEmissionList(BHeatEmission bHeatEmission)
    {
        return bHeatEmissionMapper.selectBHeatEmissionList(bHeatEmission);
    }

    /**
     * 新增热力排放
     */
    @Override
    public int insertBHeatEmission(BHeatEmission bHeatEmission)
    {
        return bHeatEmissionMapper.insertBHeatEmission(bHeatEmission);
    }

    /**
     * 修改热力排放
     */
    @Override
    public int updateBHeatEmission(BHeatEmission bHeatEmission)
    {
        return bHeatEmissionMapper.updateBHeatEmission(bHeatEmission);
    }

    /**
     * 批量删除热力排放
     */
    @Override
    public int deleteBHeatEmissionByIds(Long[] ids)
    {
        return bHeatEmissionMapper.deleteBHeatEmissionByIds(ids);
    }

    /**
     * 删除热力排放信息
     */
    @Override
    public int deleteBHeatEmissionById(Long id)
    {
        return bHeatEmissionMapper.deleteBHeatEmissionById(id);
    }


}
